import ar.com.coonocer.joy.mdg.templatehelpers.AssociationUtil;
import ar.com.coonocer.joy.mdg.templatehelpers.AttributeUtil;
import ar.com.coonocer.joy.mdg.templatehelpers.StereotypeUtil;
import ar.com.coonocer.joy.mdg.xmi.core.Attribute;
import ar.com.coonocer.joy.mdg.xmi.core.Class
import ar.com.coonocer.joy.mdg.xmi.model.Model;
import ar.com.coonocer.joy.mdg.xmi.model.Package

public class XMIGenerator{
	public static Model umlModel;
	public static TemplateUtil util = new TemplateUtil();

	public static String getXML(Model umlModel){
		XMIGenerator.umlModel = umlModel;
		//
		StringBuilder sb = new StringBuilder();
		//
		sb.append(XMIHelper.getXMIHeader());
		//
		sb.append("		<UML:Model name=\"Entities Model\" xmi.id=\"TheModel\" isRoot=\"true\" isLeaf=\"false\" isAbstract=\"false\" isSpecification=\"false\" visibility=\"public\">\r\n");
		sb.append("			<UML:Namespace.ownedElement>\r\n");
		//
		sb.append(getXMIPackageEntities());
		sb.append(getXMIPackageDatatypes());
		//
		sb.append(XMIRequirementsHelper.getXMIPackageRequirements());
		//
		sb.append(getXMIforTagDefinitions());
		sb.append(getXMIforStereotypeDefinitions());
		//
		sb.append("			</UML:Namespace.ownedElement>\r\n");
		//
		sb.append("		</UML:Model>\r\n");
		//
		sb.append(XMIHelper.getXMIFooter());
		//
		return sb.toString();
	}

	private static String getXMIPackageEntities(){
		StringBuilder sb = new StringBuilder();
		//
		sb.append("				<UML:Package name=\"Entities\" xmi.id=\"${util.nextXmiId}\" isRoot=\"true\" isLeaf=\"false\" isAbstract=\"false\" visibility=\"public\">\r\n");
		sb.append("				<UML:Namespace.ownedElement>\r\n");
		//
		//Classes
		StereotypeUtil.getNestedClassesByStereotype(XMIGenerator.umlModel, "table").each{clazz->
			sb.append(XMIClassHelper.getXMI(clazz));
		}
		//
		//Associations
		StereotypeUtil.getNestedClassesByStereotype(XMIGenerator.umlModel, "table").each{clazz->
			AssociationUtil.getAssociationsForModelElement(umlModel, clazz, AssociationUtil.FROM_THIS_ELEMENT).each{assoc->
				sb.append(XMIAssociationHelper.getXMI(assoc));
			}
		}
		//
		sb.append("				</UML:Namespace.ownedElement>\r\n");
		//
		sb.append("				</UML:Package>\r\n");
		//
		return sb.toString();
	}

	private static String getXMIPackageDatatypes(){
		StringBuilder sb = new StringBuilder();
		//
		sb.append("				<UML:Package name=\"DataTypes\" xmi.id=\"${util.nextXmiId}\" isRoot=\"true\" isLeaf=\"false\" isAbstract=\"false\" visibility=\"public\">\r\n");
		sb.append("				<UML:Namespace.ownedElement>\r\n");
		//
		util.getPrimitiveTypes().each{type->
			sb.append("				<UML:DataType xmi.id=\"Datatype_${type}\" name=\"${type}\" visibility=\"private\" isRoot=\"false\" isLeaf=\"false\" isAbstract=\"false\"/>\r\n");
		}
		//
		sb.append("				</UML:Namespace.ownedElement>\r\n");
		sb.append("				</UML:Package>\r\n");
		//
		return sb.toString();
	}

	private static String getXMIforTagDefinitions(){
		StringBuilder sb = new StringBuilder();
		//
		for (String key: XMIGenerator.util.getTaggedVales().keySet()) {
			String name = XMIGenerator.util.getTaggedVales().get(key);
			//
			sb.append("				<UML:TagDefinition xmi.id=\"${key}\" name=\"${name}\" isSpecification=\"false\" tagType=\"String\"/>\r\n");
		}
		//
		return sb.toString();
	}

	private static String getXMIforStereotypeDefinitions(){
		StringBuilder sb = new StringBuilder();
		//
		for (String key : XMIGenerator.util.getStereotypes().keySet()) {
			String name = XMIGenerator.util.getStereotypes().get(key);
			//
			sb.append("				<UML:Stereotype xmi.id=\"${key}\" name=\"${name}\" isSpecification=\"false\" isRoot=\"false\" isLeaf=\"false\" isAbstract=\"false\">\r\n");
			if (key.contains("_Class_")){
				sb.append("					<UML:Stereotype.baseClass>Class</UML:Stereotype.baseClass>\r\n");
			}else{
				sb.append("					<UML:Stereotype.baseClass>Attribute</UML:Stereotype.baseClass>\r\n");
			}
			sb.append("				</UML:Stereotype>\r\n");
		}
		//
		return sb.toString();
	}

	//Type es "Class" o "Att"
	public static String getXMIForTaggedValue(String type, String taggedValueName, Object taggedValueValue){
		StringBuilder sb = new StringBuilder();
		//
		sb.append("								<UML:TaggedValue xmi.id=\"${XMIGenerator.util.nextXmiId}\" isSpecification=\"false\">\r\n");
		sb.append("									<UML:TaggedValue.dataValue>${taggedValueValue}</UML:TaggedValue.dataValue>\r\n");
		sb.append("									<UML:TaggedValue.type><UML:TagDefinition xmi.idref=\""+XMIGenerator.util.getTaggedValueRefId(type, taggedValueName)+"\"/></UML:TaggedValue.type>\r\n");
		sb.append("								</UML:TaggedValue>\r\n");
		//
		return sb.toString();
	}

}